package com.idlecode.service;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.PlatformUI;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.idlecode.bean.DataSourceEntity;
import com.idlecode.bean.TableEntity;
import com.idlecode.bean.TableFieldEntity;
import com.idlecode.config.GenDataSource;
import com.idlecode.config.template.GeneratorConfig;
import com.idlecode.config.template.GeneratorInfo;
import com.idlecode.config.template.TemplateInfo;
import com.idlecode.util.MessageDialogUtil;
import com.idlecode.util.TemplateUtil;
import com.idlecode.util.VcsUtil;

/**
 * @program: IdleCode
 * @description
 * @author: rongjuwei
 * @create: 2024-02-18 12:01
 **/
public class GeneratorService {

	public static void generateCode(IProject project, DataSourceEntity dataSource, List<String> tableNames,
			String dataBaseName, List<String> selectedGenFileItems, boolean isFormatException) throws Exception {
		// 项目在磁盘中的路径
		String projectBasePath = project.getLocation().toOSString();
		String basePath = projectBasePath + "\\src\\main\\java\\";

		List<String> modelPathList = new ArrayList<>();
		List<String> filePathList = new ArrayList<>();
		for (String tableName : tableNames) {
			// 数据模型
			Map<String, Object> dataModel = getDataModel(dataSource, dataBaseName, tableName, selectedGenFileItems,
					isFormatException);
			if (dataModel == null) {
				continue;
			}
			modelPathList.add("src\\main\\java\\" + dataModel.get("packageName") + "\\" + dataModel.get("packagePath"));
			// 代码生成器信息
			GeneratorConfig generatorConfig = new GeneratorConfig();
			GeneratorInfo generator = generatorConfig.getGeneratorConfig(selectedGenFileItems, isFormatException);
			// 渲染模板并输出
			for (TemplateInfo template : generator.getTemplates()) {
				dataModel.put("templateName", template.getTemplateName());
				String content = TemplateUtil.getContent(template.getTemplateContent(), dataModel);
				String shortFilePathStr = TemplateUtil.getContent(template.getGeneratorPath(), dataModel);
				filePathList.add("src\\main\\java\\" + shortFilePathStr);
				// 创建文件，将内容写入到指令文件中
				String filePathStr = basePath + shortFilePathStr;
				FileUtil.writeUtf8String(content, filePathStr);
			}
		}
		// 将生成的代码自动提交到git或者svn
		String vcsType = VcsUtil.detectVcs(project);
		// String vcsType = "";
		if ("SVN".equals(vcsType)) {
			// 添加到 SVN 仓库
			// 创建 Yes/No 对话框
			boolean result = MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
					"提示", "代码生成成功！" + "\n" + "是否要将生成的文件添加到Subversion？");
			// 根据用户选择执行操作
			if (result) {
				// 用户点击了 Yes，执行相应的操作
				for (String modelPath : modelPathList) {
					String[] addCommand = { "svn", "add", modelPath, "--parents" };
					executeCommand(addCommand, projectBasePath);
				}
			}
		} else if ("Git".equals(vcsType)) {
			// 添加到git仓库
			boolean result = MessageDialog.openQuestion(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),
					"提示", "代码生成成功！" + "\n" + "是否要将生成的文件添加到Git？");
			// 添加到git仓库
			if (result) {
				for (String filePath : filePathList) {
					String[] addCommand = { "git", "add", filePath };
					executeCommand(addCommand, projectBasePath);
				}
			}
		}
	}

	/**
	 * 获取渲染的数据模型
	 *
	 * @param tableName 表ID
	 * @throws Exception
	 */
	private static Map<String, Object> getDataModel(DataSourceEntity dataSource, String dataBaseName, String tableName,
			List<String> selectedGenFileItems, boolean isFormatException) throws Exception {
		GenDataSource genDataSource = null;
		try {
			genDataSource = new GenDataSource(dataSource, dataBaseName);
			if (genDataSource.getConnection() == null) {
				MessageDialogUtil.showError("异常", "数据库连接失败！");
				return null;
			}
			// 表信息
			TableEntity table = TableService.getTableEntry(genDataSource, dataBaseName, tableName, selectedGenFileItems,
					isFormatException);
			// 字段信息
			List<TableFieldEntity> fieldList = TableFieldService.getTableFieldEntity(genDataSource, dataBaseName,
					tableName);
			// 初始化字段数据
			TableFieldService.initFieldList(fieldList, selectedGenFileItems, isFormatException);
			table.setFieldList(fieldList);

			// 数据模型
			Map<String, Object> dataModel = new HashMap<>();

			// 获取数据库类型
			String dbType = dataSource.getDbType();
			dataModel.put("dbType", dbType);

			// 项目信息
			dataModel.put("package", table.getPackageName());
			dataModel.put("packageName", table.getPackageName());
			dataModel.put("packagePath", table.getModuleName().replace(".", File.separator));
			dataModel.put("version", table.getVersion());
			dataModel.put("moduleName", table.getModuleName());
			dataModel.put("modulePath", table.getModuleName().replace(".", "/"));
			dataModel.put("modulePathTail", table.getClassName().toLowerCase());
			dataModel.put("ModuleName", CharSequenceUtil.upperFirst(table.getModuleName()));
			dataModel.put("functionName", table.getFunctionName());
			dataModel.put("FunctionName", CharSequenceUtil.upperFirst(table.getFunctionName()));

			// 开发者信息
			dataModel.put("author", table.getAuthor());
			dataModel.put("email", table.getEmail());
			dataModel.put("datetime", DateUtil.now());
			dataModel.put("date", DateUtil.today());

			// 设置字段分类
			setFieldTypeList(dataModel, table);

			// 设置基类信息
			setBaseClass(dataModel, table);

			// 导入的包列表
			List<String> importList = FieldTypeService.getPackage(fieldList);
			dataModel.put("importList", importList);

			// 表信息
			dataModel.put("tableName", table.getTableName());
			dataModel.put("tableComment", table.getTableComment());
			dataModel.put("className", CharSequenceUtil.lowerFirst(table.getClassName()));
			dataModel.put("ClassName", table.getClassName());
			dataModel.put("fieldList", table.getFieldList());

			// 生成路径
			dataModel.put("backendPath", table.getBackendPath());
			// dataModel.put("frontendPath", table.getFrontendPath());
			return dataModel;
		} catch (Exception e) {
			throw e;
		} finally {
			// 关闭连接
			try {
				if (genDataSource.getConnection() != null) {
					genDataSource.getConnection().close();
				}
			} catch (SQLException ex) {
			}
		}
	}

	/**
	 * 设置基类信息
	 *
	 * @param dataModel 数据模型
	 * @param table     表
	 */
	private static void setBaseClass(Map<String, Object> dataModel, TableEntity table) {
		if (table.getBaseclassId() == null) {
			return;
		}
		/*
		 * // 基类 BaseClassEntity baseClass =
		 * baseClassService.getById(table.getBaseclassId());
		 * baseClass.setPackageName(baseClass.getPackageName());
		 * dataModel.put("baseClass", baseClass);
		 *
		 * // 基类字段 String[] fields = baseClass.getFields().split(",");
		 *
		 * // 标注为基类字段 for (TableFieldEntity field : table.getFieldList()) { if
		 * (ArrayUtil.contains(fields, field.getFieldName())) {
		 * field.setBaseField(true); } }
		 */
	}

	/**
	 * 设置字段分类信息
	 *
	 * @param dataModel 数据模型
	 * @param table     表
	 */
	private static void setFieldTypeList(Map<String, Object> dataModel, TableEntity table) {
		// 主键列表 (支持多主键)
		List<TableFieldEntity> primaryList = new ArrayList<>();
		// 表单列表
		List<TableFieldEntity> formList = new ArrayList<>();
		// 网格列表
		List<TableFieldEntity> gridList = new ArrayList<>();
		// 查询列表
		List<TableFieldEntity> queryList = new ArrayList<>();

		for (TableFieldEntity field : table.getFieldList()) {
			if (field.isPrimaryPk()) {
				primaryList.add(field);
			}
			if (field.isFormItem()) {
				formList.add(field);
			}
			if (field.isGridItem()) {
				gridList.add(field);
			}
			if (field.isQueryItem()) {
				queryList.add(field);
			}
		}
		dataModel.put("primaryList", primaryList);
		dataModel.put("formList", formList);
		dataModel.put("gridList", gridList);
		dataModel.put("queryList", queryList);
	}

	/**
	 * 将生成的代码添加git或svn
	 *
	 * @param command
	 * @param workingDirectory
	 * @throws IOException
	 * @throws InterruptedException
	 */
	private static void executeCommand(String[] command, String workingDirectory)
			throws IOException, InterruptedException {
		ProcessBuilder processBuilder = new ProcessBuilder(command);
		processBuilder.directory(new File(workingDirectory));
		Process process = processBuilder.start();

		// 等待命令执行完毕
		int exitVal = process.waitFor();
		if (exitVal == 0) {
			System.out.println("Command executed successfully");
		} else {
			// 处理命令执行失败的情况
			System.err.println("Error executing command");
		}
	}
}
